#include<func.h>
typedef struct Con_s
{
    int netfd;
    int isAlive;
}Con_t;

int main(int argc,char*argv[])
{
    // ./server_liaotians_1 192.168.213.128 3333
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    //ipv4 结构体地址
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));//端口
    addr.sin_addr.s_addr = inet_addr(argv[1]); //地址
    //bind 和重连
    int flag = 1;
    int ret = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag));
    ret = bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));
    ERROR_CHECK(ret,-1,"bind");
    //listen
    listen(sockfd,100);//半连接队列

    //为select做准备
    char buf[4096] ={0};
    //监听和就绪队列
    fd_set rdset;
    fd_set mdset;
    FD_ZERO(&rdset);
    FD_ZERO(&mdset);
    FD_SET(STDIN_FILENO,&mdset);
    FD_SET(sockfd,&mdset);
    //结构体数组
    Con_t Client[1024];
    int Num_c = 0; //统计个数

    //while select
    while(1)
    {
        memcpy(&rdset,&mdset,sizeof(fd_set));//拷贝
        select(1024,&rdset,NULL,NULL,NULL);
        //int netfd = accept(sockfd,NULL,NULL); 写错了 写在这里说明不是很清楚
        if(FD_ISSET(sockfd,&rdset))
        {
            //说明有sockfd 准备就绪了
            int netfd = accept(sockfd,NULL,NULL);
            Client[Num_c].netfd = netfd;
            Client[Num_c].isAlive = 1;
            //加入监听队列
            FD_SET(Client[Num_c].netfd,&mdset);
            Num_c++;
        }
        //遍历监听序列
        for(int i=0; i<Num_c; i++)
        {
            if(Client[i].netfd != -1 && FD_ISSET(Client[i].netfd,&rdset))
            {
                //存活且就绪
                //接受消息
                bzero(buf,sizeof(buf));
                ssize_t sret = recv(Client[i].netfd,buf,sizeof(buf),0);
                if (sret == 0)
                {
                    //对面是关闭请求
                    Client[i].isAlive = 0;
                    //移除就绪队列
                    FD_CLR(Client[i].netfd,&mdset);
                    close(Client[i].netfd);
                    continue; //后续不需要继续执行 //这里能不能写 break;
                }
                //转发给其他连接看
                for(int j=0;j<Num_c;j++)
                {
                    //如果是自己或者已经断开
                    if(j==i || Client[j].isAlive == 0) //可能是这里的错误
                    {
                        continue;
                    }
                    send(Client[j].netfd,buf,sizeof(buf),0);
                }
            }
        }
    }
    close(sockfd);
    return 0;
}